package com.hkrt.demo.zip;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author Surpass
 * @Package com.hkrt.demo.zip
 * @Description: 多文件根据目录结构压缩
 * @date 2020/10/17 10:13
 */
public class MultipleFilesCompression {

    private static InputStream inputStream;
    private static ZipOutputStream zipOutputStream;
    private static OutputStream outputStream;

    private static String filePath = "C:\\Users\\Surpass\\Desktop\\Bypass_1.14.25";

    public static void main(String[] args) {
        try {
            //需要压缩的文件夹
            File file = new File(filePath);
            String dirName = file.getName();
            String fileParentPath = file.getParent();

            //需要生成的压缩包名称和生成路径
            outputStream = new FileOutputStream(fileParentPath+"\\"+dirName+".zip");
            zipOutputStream = new ZipOutputStream(outputStream);

            //获取目录结构
            Map<String,String> map = new HashMap<>();
            map = getFile(file, map);

            //通过key遍历map
            Set<String> keySet = map.keySet();
            Iterator<String> iterator = keySet.iterator();
            while (iterator.hasNext()){
                //key(当是空文件夹的时候key为目录，当文件夹有文件的时候key为文件名)
                String fileName = iterator.next();
                //value(当是空文件夹的时候value为""，当文件夹有文件的时候value为目录)
                String path = map.get(fileName);
                if (path.equals("")){
                    //空文件夹
                    //这里获取从压缩包开始的路径   \Bypass\Logs>>>>>>2020-09-12.txt  \Bypass\Music
                    String[] basePath = fileName.split(dirName);
                    String parent = basePath[1];
                    //压入压缩包流文件的存放路径  \Bypass\Music
                    zipOutputStream.putNextEntry(new ZipEntry(parent+"/"));
                }else {
                    //正常文件
                    //文件转输入流
                    inputStream = new FileInputStream(path+"\\"+fileName);
                    //这里获取从压缩包开始的路径   \Bypass\Logs>>>>>>2020-09-12.txt  \Bypass>>>>>>使用须知.txt
                    String[] basePath = path.split(dirName);
                    String parent = basePath[1];
                    zipOutputStream.putNextEntry(new ZipEntry(parent +"\\"+fileName));
                }
                //写文件
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = inputStream.read(bytes))!=-1){
                    zipOutputStream.write(bytes,0,len);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //关闭
            try {
                if (zipOutputStream!=null){
                    zipOutputStream.closeEntry();
                    zipOutputStream.close();
                }
                if (outputStream!=null){
                    outputStream.close();
                }
                if (inputStream!=null){
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * @Description: 使用递归的方式向map中存入目录结构
     * @param file, 需要压缩的文件
     *        map 存放目录结构
     * @return java.util.Map<java.lang.String,java.lang.String>
     * @throws
     * @author Surpass
     * @date 2020/10/17 11:26
     */
    private static Map<String,String> getFile(File file,Map<String,String> map){
        File[] files = file.listFiles();
        //如果是空文件夹的时候使用路径作为key
        if (files.length==0){
            map.put(file.getAbsolutePath(),"");
        }
        for (File file1 : files) {
            if (file1.isDirectory()){
                //递归
                getFile(file1,map);
            }
            if (file1.isFile()){
                //文件作为key，路径作为value
                map.put(file1.getName(),file1.getParent());
            }
        }
        return map;
    }
}
